package com.example.jmeter.util;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.io.*;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.*;

public class ZipUtil {

    public static void main(String[] args) {
        String zipFilePath = "E:\\gitee\\spring-agent\\download\\apache-jmeter_5.5.zip";
        String outputFolder = "E:\\tmp\\Jmeter";
        unZip(zipFilePath, outputFolder, "jmeter-5.5");
    }
    /**
     * 解压文件
     * @param zipFilePath 解压文件路径
     * @param outputFolder 输出解压文件路径
     */
    public static void unZip(String zipFilePath, String outputFolder, String reName){
        byte[] buffer = new byte[1024];
        File folder = new File(outputFolder);
        if (!folder.exists()){
            folder.mkdir();
        }
        File newFile = null;
        // get the zip file content
        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath));) {
            ZipEntry ze = zis.getNextEntry();
            while (ze != null){
                String fileName = ze.getName();
                newFile = new File(outputFolder + File.separator + fileName);
                //create all non exists folders
                //else you will hit FileNotFoundException for compressed folder
                //大部分网络上的源码，这里没有判断子目录
                if (ze.isDirectory()){
                    newFile.mkdirs();
                }else{
                    new File(newFile.getParent()).mkdirs();
                    try (FileOutputStream fos = new FileOutputStream(newFile);) {
                        int len;
                        while ((len = zis.read(buffer))!=-1){
                            fos.write(buffer,0,len);
                        }
                    }
                }
                ze = zis.getNextEntry();
            }
            zis.closeEntry();
        }catch (Exception e){
            throw new RuntimeException("解压失败！", e);
        }
        if (newFile == null) {
            return;
        }
        boolean reNameFlag = newFile.renameTo(new File(outputFolder + File.separator + reName));
        Assert.isTrue(reNameFlag, "压缩文件重命名失败");
        newFile.delete();
    }

    /**
     * 把所有文件都直接解压到指定目录(忽略子文件夹)
     * @param zipFile
     * @param folderPath
     * @throws ZipException
     * @throws IOException
     */
    public static void upZipFile(File zipFile, String folderPath) throws ZipException, IOException {
        File desDir = new File(folderPath);
        if (!desDir.exists()) {
            desDir.mkdirs();
        }
        ZipFile zf = new ZipFile(zipFile);
        for (Enumeration<?> entries = zf.entries(); entries.hasMoreElements(); ) {
            ZipEntry entry = ((ZipEntry) entries.nextElement());
            InputStream in = zf.getInputStream(entry);
            String str = folderPath;
            // str = new String(str.getBytes("8859_1"), "GB2312");
            File desFile = new File(str, java.net.URLEncoder.encode(entry.getName(), "UTF-8"));

            if (!desFile.exists()) {
                File fileParentDir = desFile.getParentFile();
                if (!fileParentDir.exists()) {
                    fileParentDir.mkdirs();
                }
            }

            OutputStream out = new FileOutputStream(desFile);
            byte buffer[] = new byte[1024 * 1024];
            int realLength = in.read(buffer);
            while (realLength != -1) {
                out.write(buffer, 0, realLength);
                realLength = in.read(buffer);
            }

            out.close();
            in.close();

        }
    }

    /**
     * 解压目录下的zip文件到指定目录
     *
     * @param jarPath
     * @param destDirPath
     * @throws Exception
     */
    public static void unJarFile(String jarPath, String destDirPath) {
        try (JarFile jarFile = new JarFile(jarPath)) {
            Enumeration<?> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = (JarEntry) entries.nextElement();
                // 如果是文件夹，就创建个文件夹
                if (entry.isDirectory()) {
                    String dirPath = destDirPath + "/" + entry.getName();
                    File dir = new File(dirPath);
                    dir.mkdirs();
                } else {
                    // 如果是文件，就先创建一个文件，然后用io流把内容copy过去
                    File targetFile = new File(destDirPath + "/" + entry.getName());
                    // 保证这个文件的父文件夹必须要存在
                    if (!targetFile.getParentFile().exists()) {
                        targetFile.getParentFile().mkdirs();
                    }
                    targetFile.createNewFile();
                    // 将压缩文件内容写入到这个文件中
                    try (InputStream is = jarFile.getInputStream(entry);
                         FileOutputStream fos = new FileOutputStream(targetFile);) {
                        int len;
                        int BUFFER_SIZE = 1024;
                        byte[] buf = new byte[BUFFER_SIZE];
                        while ((len = is.read(buf)) != -1) {
                            fos.write(buf, 0, len);
                        }
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("unzip error from ZipUtils", e);
        }
    }


}